<!--
描述：公共查询页面业务逻辑基础类
路径：/components/search-view/index.vue
作者：王鑫
时间：2018-6-25
-->
<template>
  <div class="searchable">
    <div ref="toolbarView" class="searchable-row">
      <Input v-if="blurSearch" v-model="table.filter.keyword" placeholder="关键字查找"
        icon="ios-search" clearable class="width-200" @on-enter="search" />
      <slot name="search"></slot>
      <Button @click="search(table.filter, 1)" :loading="working.search"
        icon="ios-search">搜索</Button>
      <slot name="header"></slot>
      <!-- 高级查询按钮 -->
      <ActionButton v-if="$scopedSlots['filter']" content="高级搜索" in-line
        :active="advanceVisible" @click="advanceVisible=!advanceVisible" />
      <Button v-if="working.creatable" icon="md-add" type="primary"
        @click="__dispatch('onCreate')">添加</Button>
      <slot name="action"></slot>
      <BatchRemoveButton v-if="working.deletable" :disabled="table.selectRowCount==0"
        :working="working" @on-ok="__dispatch('onRemoveAll',getSelection());" />
      <ActionButton v-if="!hideCustomColumn" content="自定义" in-line :active="customVisible"
        @click="customVisible=!customVisible" />
      <ExportButton v-if="working.exportable" @click="onExportClick" />
    </div>
    <div v-if="advanceVisible" ref="advanceView" class="searchable-row">
      <slot name="filter"></slot>
    </div>
    <CustomColumnView ref="customView" v-if="customVisible" :table="table" />
    <div ref="dataView" class="searchable-content">
      <template v-if="$scopedSlots['table-slot']">
        <slot name="table-slot"></slot>
      </template>
      <template v-else>
        <DefaultTableView ref="selection" :table="table" :working="working" />
      </template>
    </div>
    <PaperView ref="paperView" :paper="paper" />
    <slot></slot>
  </div>
</template>

<script>
import PaperView from './components/paper-view';
import ExportButton from './components/export-button';
import DefaultTableView from './components/default-table-view';
import CustomColumnView from './components/custom-column-view';
import BatchRemoveButton from './components/batch-remove-button';
import { ViewTable, ViewPaper, ViewWorking } from '_/schema';
import ActionButton from '../ActionButton/ActionButton';

export default {
  name: 'SearchView',
  props: {
    /** 表示页面是否处于高级检索状态 */
    advance: {
      type: Boolean,
      default: false
    },
    /** 获取或设置一个值，该值指定组件是否启用模糊查询，默认为ture */
    blurSearch: {
      type: Boolean,
      default: true
    },
    /** 获取或设置一个值，该值指定组件是否隐藏自定义表格项，默认为false */
    hideCustomColumn: {
      type: Boolean,
      default: false
    }
  },

  data() {
    return {
      table: new ViewTable(),
      paper: new ViewPaper(),
      working: new ViewWorking(),
      /** boolean，表示字段自定义区域是否可见,true表示可见 */
      customVisible: false,
      /** boolean，表示页面是否处于高级检索状态 */
      advanceVisible: this.advance
    };
  },

  methods: {
    // interface
    search(filter, index, size) {},

    initDispatch() {
      this.__dispatch(`onMounted`, this.table.filter);
    },

    getSelection() {
      return this.table.selection;
    },

    /** 导出按钮点击事件处理函数 */
    onExportClick(action) {
      switch (action) {
        case 'client':
          this.__dispatch(`onExport`, this.$refs.selection);
          break;
        case 'server':
          this.__dispatch(`onExportAll`, this.table.filter);
          break;
      }
    },

    /** 当浏览器窗口改变大小时触发，用于计算表格高度 */
    resize() {
      // 页面内容区高度
      let contentHeight = this.$el.offsetHeight;
      let toolbarHeight = this.$refs.toolbarView.offsetHeight;
      let paperHeight = this.$refs.paperView.$el.offsetHeight;

      let dataHeight = contentHeight - toolbarHeight - paperHeight;

      if (this.$refs.advanceView) {
        let advanceHeight = this.$refs.advanceView.offsetHeight;
        dataHeight -= advanceHeight;
      }

      if (this.$refs.customView) {
        let customViewHeight = this.$refs.customView.$el.offsetHeight;
        dataHeight -= customViewHeight;
      }

      this.table.height = dataHeight;
      this.__dispatch(`onResize`);
    },

    __handle_window_resize() {
      this.$nextTick(this.resize);
    },

    /**
     * 调用宿主方法
     * @param {string} method 宿主方法名称
     * @param {any} options 调用宿主方法时传入的参数
     * @returns {Promise}
     */
    __dispatch(method, options) {
      return new Promise(resolve => {
        if (typeof this.$parent[method] === 'function') {
          let result = this.$parent[method](options);
          if (result) {
            result.then(resolve);
          } else {
            resolve(result);
          }
        } else {
          console.warn(`未重写 ${method} 事件，本提示对功能没有任何影响。`);
          resolve();
        }
      });
    },

    /**
     * 为宿主注入方法或属性
     * @param {string} 方法或属性名称
     * @param {any} 值
     */
    __commit(name, instance) {
      this.$parent[name] = instance;
    }
  },

  watch: {
    advanceVisible() {
      this.__handle_window_resize();
    },
    customVisible() {
      this.__handle_window_resize();
    }
  },

  mounted() {
    this.__handle_window_resize();
    window.addEventListener('resize', this.__handle_window_resize);
    this.initDispatch();
  },

  destroyed() {
    window.removeEventListener('resize', this.__handle_window_resize);
  },

  components: {
    PaperView,
    ExportButton,
    DefaultTableView,
    CustomColumnView,
    BatchRemoveButton,
    ActionButton
  }
};
</script>

<style lang="less" scoped>
@import '../../../../framework/assets/styles/theme.less';
.searchable {
  display: flex;
  flex-direction: column;
  height: 100%;
  &-content {
    flex: 1;
  }
  &-row {
    background-color: #fff;
    border-color: @border-color-base;
    border-width: @border-width-base;
    border-style: @border-style-base;
    border-bottom: none;
    padding: 8px 0 0 0;

    &:last-child {
      border-color: @border-color-base;
      border-width: @border-width-base;
      border-style: @border-style-base;
      border-top: none;
    }
  }
}
</style>

<style lang="less">
.searchable-row {
  & > *,
  & > .ivu-input-wrapper,
  & > .ivu-btn,
  & > .ivu-dropdown,
  & > .ivu-select,
  & > .ivu-poptip,
  & > .ivu-date-picker {
    margin-bottom: 8px !important;
    margin-left: 8px;
    vertical-align: middle;
  }
}
</style>
